import React, { useEffect } from "react";
// import './index.css';
import {
  Attachments,
  Bubble,
  Conversations,
  Prompts,
  Sender,
  Welcome,
  useXAgent,
  useXChat,
} from "@ant-design/x";
import { createStyles } from "antd-style";
import OpenAI from "openai";
import markdownit from "markdown-it";
import {
  CloudUploadOutlined,
  CommentOutlined,
  CopyOutlined,
  EllipsisOutlined,
  FireOutlined,
  HeartOutlined,
  PaperClipOutlined,
  PlusOutlined,
  ReadOutlined,
  ShareAltOutlined,
  SmileOutlined,
  SyncOutlined,
} from "@ant-design/icons";
import { Badge, Button, Space, Typography } from "antd";
import { UserOutlined } from "@ant-design/icons";

// 配置信息
// const apikey = 'sk-68ac5f5ccf3540ba834deeeaecb48987'
// const baseUrl = 'https://dashscope.aliyuncs.com/compatible-mode/v1'
// const modelName = 'qwen-plus'

const apikey = "empty";
const baseUrl = "http://8.140.229.23:8576/o1";
const modelName = "chatbi-turbo";

// 初始化模型实例
const client = new OpenAI({
  baseURL: baseUrl,
  apiKey: apikey,
  dangerouslyAllowBrowser: true,
});

const fooAvatar = {
  color: "#f56a00",
  backgroundColor: "#fde3cf",
};
const barAvatar = {
  color: "#fff",
  backgroundColor: "#87d068",
};

const md = markdownit({ html: true, breaks: true });

const renderTitle = (icon: any, title: any) => (
  <Space align="start">
    {icon}
    <span>{title}</span>
  </Space>
);
const defaultConversationsItems = [
  {
    key: "0",
    label: "What is Ant Design X?",
  },
];
const useStyle = createStyles(({ token, css }) => {
  return {
    layout: css`
      width: 100%;
      min-width: 1000px;
      height: 722px;
      border-radius: ${token.borderRadius}px;
      display: flex;
      background: ${token.colorBgContainer};
      font-family: AlibabaPuHuiTi, ${token.fontFamily}, sans-serif;

      .ant-prompts {
        color: ${token.colorText};
      }
    `,
    menu: css`
      background: ${token.colorBgLayout}80;
      width: 280px;
      height: 100vh;
      display: flex;
      flex-direction: column;
    `,
    conversations: css`
      padding: 0 12px;
      flex: 1;
      overflow-y: auto;
    `,
    chat: css`
      height: 100vh;
      width: 100%;
      max-width: 900px;
      margin: 0 auto;
      box-sizing: border-box;
      display: flex;
      flex-direction: column;
      padding: ${token.paddingLG}px;
      gap: 16px;
    `,
    messages: css`
      flex: 1;
    `,
    placeholder: css`
      padding-top: 32px;
    `,
    sender: css`
      width: 100%;
      box-shadow: ${token.boxShadow};
    `,
    logo: css`
      display: flex;
      height: 72px;
      align-items: center;
      justify-content: start;
      padding: 0 24px;
      box-sizing: border-box;

      img {
        width: 24px;
        height: 24px;
        display: inline-block;
      }

      span {
        display: inline-block;
        margin: 0 8px;
        font-weight: bold;
        color: ${token.colorText};
        font-size: 16px;
      }
    `,
    addBtn: css`
      background: #1677ff0f;
      border: 1px solid #1677ff34;
      width: calc(100% - 24px);
      margin: 0 12px 24px 12px;
    `,
  };
});
const placeholderPromptsItems = [
  {
    key: "1",
    label: renderTitle(
      <FireOutlined
        style={{
          color: "#FF4D4F",
        }}
      />,
      "数据分析与洞察"
    ),
    description: "取数、分析与洞察",
    children: [
      {
        key: "1-1",
        description: `飞往巴黎的航班有哪些？`,
      },
      {
        key: "1-2",
        description: `分析一下国航的燃油经济性`,
      },
      {
        key: "1-3",
        description: `用折线图画南航的客均票价`,
      },
    ],
  },
  {
    key: "2",
    label: renderTitle(
      <FireOutlined
        style={{
          color: "#1890FF",
        }}
      />,
      "对话式数据编辑"
    ),
    description: "您的高效办公助理",
    children: [
      {
        key: "2-1",
        description: `表格最后一列加上'载客燃油比'`,
      },
      {
        key: "2-2",
        description: `将第2列和第5列互换位置`,
      },
      {
        key: "2-3",
        description: `将东京的数据单独存为一个sheet`,
      },
    ],
  },
  {
    key: "3",
    label: renderTitle(
      <FireOutlined
        style={{
          color: "#1890FF",
        }}
      />,
      "数据智能可视化"
    ),
    description: "智能可交互式图表",
    children: [
      {
        key: "3-1",
        description: `画出各航司的客均票价`,
      },
      {
        key: "3-2",
        description: `将东航从图中删掉`,
      },
      {
        key: "3-3",
        description: `把颜色换成红色和绿色`,
      },
    ],
  },
];
const senderPromptsItems = [
  {
    key: "1",
    description: "不知道问什么？找找灵感！",
    icon: (
      <FireOutlined
        style={{
          color: "#FF4D4F",
        }}
      />
    ),
  },
];
const roles: any = {
  ai: {
    placement: "start",
    typing: {
      step: 5,
      interval: 20,
    },
    styles: {
      content: {
        borderRadius: 16,
      },
    },
  },
  local: {
    placement: "end",
    variant: "shadow",
  },
};
const Home = () => {
  // ==================== Style ====================
  const { styles } = useStyle();

  // ==================== State ====================
  const [headerOpen, setHeaderOpen] = React.useState(false);
  const [content, setContent] = React.useState("");
  const [conversationsItems, setConversationsItems] = React.useState(
    defaultConversationsItems
  );
  const [activeKey, setActiveKey] = React.useState(
    defaultConversationsItems[0].key
  );
  const [attachedFiles, setAttachedFiles] = React.useState([]);
  const [searchLoading, setSearchLoading] = React.useState(false);
  const abortRef = React.useRef(false); // 创建一个 ref 来存储中断标志

  // 添加 ref
  const attachmentsRef = React.useRef<any>(null);
  const senderRef = React.useRef<any>(null);

  // ==================== Runtime ====================
  const [agent] = useXAgent({
    request: async (info, callbacks: any) => {
      const { messages, message } = info;
      const { onSuccess, onUpdate, onError } = callbacks;
      let content: string = "";
      let aiMessageComplete = false; // 标记AI消息是否接收完整

      try {
        const stream = await client.chat.completions.create({
          model: modelName,
          messages: [
            {
              role: "user",
              content: `${message}`,
              source: "airline",
            } as any,
          ],
          stream: true,
        });

        for await (const chunk of stream) {
          if (abortRef.current) {
            // 检查中断标志
            break; // 中断循环
          }

          const responseText = chunk.choices[0]?.delta?.content || "";
          content += responseText;
          console.log(responseText);

          // 如果流式最后接受到空字符串，为截止
          if (responseText === "" && content.trim() !== "") {
            aiMessageComplete = true;
            setSearchLoading(false);
          }
          onUpdate(content);
        }
        onSuccess(content);
      } catch (error) {
        console.log("error:", error);
      }
    },
  });
  const { onRequest, messages, setMessages } = useXChat({
    agent,
  });
  useEffect(() => {
    if (activeKey !== undefined) {
      setMessages([]);
    }
  }, [activeKey]);

  // ==================== Event ====================
  const onSubmit = (nextContent: any) => {
    if (!nextContent) return;
    onRequest(nextContent);
    setContent("");
  };
  const handleAbort = () => {
    abortRef.current = true;
  };
  const onPromptsItemClick = (info: any) => {
    onRequest(info.data.description);
  };
  const onAddConversation = () => {
    setConversationsItems([
      ...conversationsItems,
      {
        key: `${conversationsItems.length}`,
        label: `New Conversation ${conversationsItems.length}`,
      },
    ]);
    setActiveKey(`${conversationsItems.length}`);
  };
  const onConversationClick = (key: any) => {
    setActiveKey(key);
  };
  const handleFileChange = (info: any) => setAttachedFiles(info.fileList);

  // 添加复制功能
  const handleCopy = (content: string) => {
    navigator.clipboard.writeText(content);
  };

  // 添加重新生成功能
  const handleRegenerate = (message: string) => {
    if (message) {
      onRequest(message);
    }
  };

  // ==================== Nodes ====================
  const placeholderNode = (
    <Space direction="vertical" size={16} className={styles.placeholder}>
      <Welcome
        variant="borderless"
        icon="https://mdn.alipayobjects.com/huamei_iwk9zp/afts/img/A*s5sNRo5LjfQAAAAAAAAAAAAADgCCAQ/fmt.webp"
        title="Hello, 我是梧桐ChatBI"
        description="您在数据分析领域的原⽣数据助理，我可以帮您高效地实现NL2SQL、数据问答、
数据分析、数据洞察等多维度的⼤模型智能分析应⽤~"
        extra={
          <Space>
            <Button icon={<ShareAltOutlined />} />
            <Button icon={<EllipsisOutlined />} />
          </Space>
        }
      />
      <Prompts
        title="您可以试着这样提问"
        items={placeholderPromptsItems}
        styles={{
          list: {
            width: "100%",
          },
          item: {
            flex: 1,
          },
        }}
        onItemClick={onPromptsItemClick}
      />
    </Space>
  );
  const items = messages.map(({ id, message, status }) => ({
    key: id,
    loading: status === "loading",
    role: status === "local" ? "local" : "ai",
    content: message,
  }));
  const attachmentsNode = (
    <Badge dot={attachedFiles.length > 0 && !headerOpen}>
      <Button
        type="text"
        icon={<PaperClipOutlined />}
        onClick={() => setHeaderOpen(!headerOpen)}
      />
    </Badge>
  );
  const senderHeader = (
    <Sender.Header
      title="Attachments"
      open={headerOpen}
      onOpenChange={setHeaderOpen}
      styles={{
        content: {
          padding: 0,
        },
      }}
      forceRender
    >
      <Attachments
        ref={attachmentsRef}
        beforeUpload={() => false}
        items={attachedFiles}
        onChange={handleFileChange}
        placeholder={(type) =>
          type === "drop"
            ? {
                title: "Drop file here",
              }
            : {
                icon: <CloudUploadOutlined />,
                title: "Upload files",
                description: "Click or drag files to this area to upload",
              }
        }
        getDropContainer={() => senderRef.current?.nativeElement}
      />
    </Sender.Header>
  );
  const logoNode = (
    <div className={styles.logo}>
      <img
        src="https://mdn.alipayobjects.com/huamei_iwk9zp/afts/img/A*eco6RrQhxbMAAAAAAAAAAAAADgCCAQ/original"
        draggable={false}
        alt="logo"
      />
      <span>梧桐 ChatBI</span>
    </div>
  );
  const renderMarkdown = (content: any) => (
    <Typography>
      <div dangerouslySetInnerHTML={{ __html: md.render(content) }} />
    </Typography>
  );
  // ==================== Render =================
  return (
    <div className={styles.layout}>
      <div className={styles.menu}>
        {/* 🌟 Logo */}
        {logoNode}
        {/* 🌟 添加会话 */}
        <Button
          onClick={onAddConversation}
          type="link"
          className={styles.addBtn}
          icon={<PlusOutlined />}
        >
          New Conversation
        </Button>
        {/* 🌟 会话管理 */}
        <Conversations
          items={conversationsItems}
          className={styles.conversations}
          activeKey={activeKey}
          onActiveChange={onConversationClick}
        />
      </div>
      <div className={styles.chat}>
        {/* 🌟 消息列表 */}
        <div style={{ flex: 1, overflowY: "scroll", scrollbarWidth: "none" }}>
          <div style={{ height: "100%" }}>
            {messages.length === 0
              ? placeholderNode
              : messages.map((item: any) => {
                  return (
                    <Bubble
                      key={item.id}
                      placement={item.status === "local" ? "end" : "start"}
                      content={renderMarkdown(item.message)}
                      header={item.status === "local" ? "" : "梧桐ChatBI"}
                      avatar={{
                        icon: <UserOutlined />,
                        style: item.status === "local" ? barAvatar : fooAvatar,
                      }}
                      style={{ margin: "10px 0" }}
                      footer={
                        item.status !== "local" && (
                          <Space size={8}>
                            <Button
                              type="text"
                              size="small"
                              icon={<SyncOutlined />}
                              onClick={() => handleRegenerate(item.message)}
                            />
                            <Button
                              type="text"
                              size="small"
                              icon={<CopyOutlined />}
                              onClick={() => handleCopy(item.message)}
                            />
                          </Space>
                        )
                      }
                    />
                  );
                })}
          </div>
        </div>
        {/* 🌟 输入框 */}
        <Prompts
          items={senderPromptsItems}
          onItemClick={onPromptsItemClick}
          style={{ margin: "16px 0" }}
        />
        {/* 🌟 提示词 */}
        <Sender
          ref={senderRef}
          value={content}
          header={senderHeader}
          onSubmit={onSubmit}
          onChange={setContent}
          prefix={attachmentsNode}
          loading={agent.isRequesting()}
          className={styles.sender}
          onPasteFile={(file) => {
            attachmentsRef.current?.upload(file);
            setHeaderOpen(true);
          }}
        />
      </div>
    </div>
  );
};

export default Home;
